The prototype of pfxopen() is as follows:
The argument values areint pfxopen(dev_t *devp, int oflag, int otyp, cred_t *crp);
*devp | Pointer to a dev_t value from which you can extract both the major and minor device numbers. |
otyp | An integer flag specifying the source of the call: a user process opening a character device or block device, or another driver. |
oflag | Flag bits specifying user mode options on the open() call. |
crp | A cred_t object--an opaque structure for use in authentication. Standard access privileges to the special device file have already been verified. |
Note: When the driver's pfxdevflag entry contains D_OLD or when pfxdevflag is not defined, the first argument to pfxopen() is a dev_t value, not a pointer to a dev_t value. See "Flag D_OLD". In general, the driver is expected to verify that this user process is permitted access in the way specified in otyp (reading, writing, or both) for the device specified in *devp. If access is not allowable, the driver returns a nonzero error code from sys/errno.h, for example ENOMEM or EBUSY.
When the driver supports the pfxedtinit() entry, the driver needs a way to associate the different edt_t structures passed to pfxedtinit() with the device numbers passed to pfxopen() and other routines. One solution is to require that the ctlr= value from the VECTOR statement--which is passed in the e_ctlr field of edt_t--must be the same as the device minor number.
It is possible to have the same driver treated as both block and character, in which case the driver needs to know whether the open() call addressed a block or character special device. It is possible for a block device to support different partitions with different uses, in which case the driver might need to record the fact that a device has been mounted, or opened as a swap device.
With all open types except OTYP_LYR, pfxopen() is called for every open or mount operation, but pfxclose() is called only when the last close or unmount occurs. The OTYP_LYR feature is used almost exclusively by drivers distributed with IRIX, like the host adapter SCSI driver (see "Host Adapter Concepts"). For each open of this type, there is one call to pfxclose().
FREAD | Input access wanted. |
FWRITE | Output access wanted (both FREAD and FWRITE may be set, corresponding to O_RDWR mode). |
FNDELAY or FNONBLOCK | Return at once, do not sleep if the open cannot be done immediately. |
FEXCL | Request exclusive use of the device. |
You decide which of the flags have meaning with respect to the abilities of this device. You can return an EINVAL error when an unsupported mode is requested.
A key decision is whether the device can be opened only by one process at a time, or by multiple processes. If multiple opens are supported, a process can still request exclusive access with the FEXCL mode.
When the device can be used by only one process, or when FEXCL access is supported, the driver must keep track of the fact that the device is open. When the device is busy, the driver can test the FNDELAY and FNONBLOCK flags; if either is set, it can return EBUSY. Otherwise, the driver should sleep until the device is free; this requires coordination with the pfxclose() entry point.